/*
 *  Copyright 2015-2016, RenGu Technology (BeiJing) Co., Ltd.
 *  All right reserved.
 *
 *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF RENGU TECHNOLOGY (BeiJing) CO., LTD.
 *
 *  THE CONTENTS OF THIS FILE MAY NOT BE DISCLOSED TO THIR PARTIES,
 *  COPIED OR DUPLICATED IN ANY FORM, IN WHOLE OR IN PART,
 *  WITHOUT THE PRIOR WRITTEN PERMISSION OF RENGU TECHNOLOGY (BeiJing) CO., LTD.
 *
 *  VirtAcctPreAuth
 *
 *  Edit History:
 *      lizhangtao Created on 2020年04月12日
 *
 */
package cc.rengu.igas.acct.core.service.trans;

import cc.rengu.igas.acct.common.dao.MapperCommon;
import cc.rengu.igas.acct.common.entity.AcctDetail;
import cc.rengu.igas.acct.common.entity.AcctInfo;
import cc.rengu.igas.acct.common.enums.AcctRespCodeEnum;
import cc.rengu.igas.acct.common.enums.AcctTransStatusEnum;
import cc.rengu.igas.acct.common.util.CheckAcct3o1;
import cc.rengu.igas.acct.common.util.CheckCutDayUtil;
import cc.rengu.igas.acct.common.util.QueryAcct3o1;
import cc.rengu.igas.acct.core.service.realize.AcctOpt;
import cc.rengu.igas.acct.facade.bean.MultiMchntPreAuthDetail;
import cc.rengu.igas.acct.facade.request.VirtAcctMultiMchntPreAuthRequest;
import cc.rengu.igas.acct.facade.response.VirtAcctMultiMchntPreAuthResponse;
import cc.rengu.oltp.service.base.RadpService;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.DbsUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.base.StringUtil;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.List;

/**
 * 多商户预授权
 * 冻结多商户交易金额
 * 从可用余额转到冻结余额，整体账户余额不变
 *
 * @author lizhangtao
 * @version 1.0
 * @date 2020/5/29
 */
public class VirtAcctMultiMchntPreAuthService extends RadpService {

    @Override
    protected int bizInit(String s) {
        return 0;
    }

    @Override
    protected int bizProcess(String s, int i) {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        VirtAcctMultiMchntPreAuthRequest virtAcctMultiMchntPreAuthRequest = new VirtAcctMultiMchntPreAuthRequest();
        VirtAcctMultiMchntPreAuthResponse virtAcctMultiMchntPreAuthResponse = new VirtAcctMultiMchntPreAuthResponse();
        try {
            ConvertUtil.convertOutput(virtAcctMultiMchntPreAuthRequest);
            rglog.info("virtAcctMultiMchntPreAuthRequest = <{}>", JSONObject.toJSONString(virtAcctMultiMchntPreAuthRequest));

            virtAcctMultiMchntPreAuthResponse.setHeader(virtAcctMultiMchntPreAuthRequest.getHeader());
            BizResponse<VirtAcctMultiMchntPreAuthResponse> bizResponse = new BizResponse<>();
            bizResponse.setResult(virtAcctMultiMchntPreAuthResponse);
            String txnDate = virtAcctMultiMchntPreAuthRequest.getHeader().getTransDate();
            String txnTime = virtAcctMultiMchntPreAuthRequest.getHeader().getTransTime();
            String txnNum = virtAcctMultiMchntPreAuthRequest.getHeader().getTxnNum();
            String traceNo = virtAcctMultiMchntPreAuthRequest.getHeader().getTraceNo();
            String instId = virtAcctMultiMchntPreAuthRequest.getHeader().getInstId();
            String srcSysId = virtAcctMultiMchntPreAuthRequest.getHeader().getSrcSysId();
            List<MultiMchntPreAuthDetail> multiMchntPreAuthDetailList = virtAcctMultiMchntPreAuthRequest.getMultiMchntPreAuthDetailList();
            if (null == multiMchntPreAuthDetailList || 0 == multiMchntPreAuthDetailList.size() || 100 < multiMchntPreAuthDetailList.size()) {
                rglog.error("多商户预授权详细信息必须上送且不能超过100");
                throw new BizException(AcctRespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(),
                        AcctRespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
            }
            if (StringUtil.isNullorEmpty(traceNo) || StringUtil.isNullorEmpty(instId)) {
                rglog.error("冻结失败:instId、traceNo必须上送");
                throw new BizException(AcctRespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(),
                        AcctRespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
            }
            //2. 开启事物
            String dbPoolName = MapperCommon.getDbPoolName();
            DbsUtil dbsUtil = new DbsUtil(dbPoolName);
            dbsUtil.dbsBeginTransaction();
            try {
                //检查记账日期
                String acctDate = CheckCutDayUtil.check(instId, dbsUtil);
                for (MultiMchntPreAuthDetail multiMchntPreAuthDetail : multiMchntPreAuthDetailList) {
                    //检查明细
                    CheckAcct3o1.checkReq(multiMchntPreAuthDetail.getAcctNo(), multiMchntPreAuthDetail.getCustomerId(),
                            multiMchntPreAuthDetail.getUserType(), multiMchntPreAuthDetail.getUserId(), multiMchntPreAuthDetail.getTransAmt(), rglog);
                    //增加xml树对象赋值
                    xmlTreeUtil.setXmlTreeObjectValue("currentMultMchntPreAuthDetailObj", multiMchntPreAuthDetail);
                    //调用冻结操作
                    AcctDetail acctDetail = new AcctOpt().freeze(txnDate, txnTime, txnNum, srcSysId, instId, traceNo, multiMchntPreAuthDetail.getTransAmt(),
                            multiMchntPreAuthDetail.getAcctNo(), multiMchntPreAuthDetail.getCustomerId(),
                            multiMchntPreAuthDetail.getUserType(), multiMchntPreAuthDetail.getUserId(),
                            multiMchntPreAuthDetail.getSummary(), rglog, acctDate, dbsUtil, multiMchntPreAuthDetailList.size());

                    multiMchntPreAuthDetail.setAfterBalance(acctDetail.getAfterBalance());
                    multiMchntPreAuthDetail.setAfterAvailableBalance(acctDetail.getAfterAvailableBalance());
                    multiMchntPreAuthDetail.setAfterFreezeBalance(acctDetail.getAfterFreezeBalance());
                    multiMchntPreAuthDetail.setAcctDate(acctDetail.getAcctDate());
                    multiMchntPreAuthDetail.setAcctSeqNum(acctDetail.getAcctSeqNum());
                    virtAcctMultiMchntPreAuthResponse.setAcctDate(acctDetail.getAcctDate());
                }
                //再次检查记账日期
                new AcctOpt().acctDateConfirm(instId, acctDate, dbsUtil, rglog);
            } catch (Exception e) {
                dbsUtil.dbsEndTransaction(false);
                throw e;
            }
            dbsUtil.dbsEndTransaction(true);
            virtAcctMultiMchntPreAuthResponse.setMchtPreAuthDetailList(multiMchntPreAuthDetailList);
            virtAcctMultiMchntPreAuthResponse.setRespCode(OltpRpcdEnum.TRANS_SUCCESS.getRespCode());
            virtAcctMultiMchntPreAuthResponse.setRespDesc(OltpRpcdEnum.TRANS_SUCCESS.getRespDesc());
            virtAcctMultiMchntPreAuthResponse.setTransStatus(AcctTransStatusEnum.SUCC.getStatus());
            bizResponse.setRspSysId(ChannelEnum.ACCT.getChannelType());
            bizResponse.setTransStatus(TransStatusEnum.TRANS_SUCC);
            bizResponse.setRespCode(OltpRpcdEnum.TRANS_SUCCESS.getRespCode());
            bizResponse.setRespDesc(OltpRpcdEnum.TRANS_SUCCESS.getRespDesc());
            ConvertUtil.convertInput(bizResponse.getResult());
        } catch (BizException e) {
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, e.getCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, e.getMessage());
                //当且仅当返回余额不足时，报余额不足的商户返回当前账户余额信息，LIST中仅一条数据
                if (AcctRespCodeEnum.BALBNCE_NOT_ENOUGH_ERROR.getRespCode().equals(e.getCode())) {
                    //获取异常抛出时的对象
                    MultiMchntPreAuthDetail currentMultMchntPreAuthDetailObj = (MultiMchntPreAuthDetail) xmlTreeUtil.getXmlTreeObjectValue("currentMultMchntPreAuthDetailObj", MultiMchntPreAuthDetail.class);
                    //查询虚拟账户余额
                    String dbPoolName = MapperCommon.getDbPoolName();
                    DbsUtil dbsUtil = new DbsUtil(dbPoolName);
                    AcctInfo acctInfo = QueryAcct3o1.queryAcctInfo(virtAcctMultiMchntPreAuthRequest.getHeader().getInstId(),
                            currentMultMchntPreAuthDetailObj.getAcctNo(), currentMultMchntPreAuthDetailObj.getCustomerId(),
                            currentMultMchntPreAuthDetailObj.getUserType(), currentMultMchntPreAuthDetailObj.getUserId(), dbsUtil, rglog);
                    //赋值
                    currentMultMchntPreAuthDetailObj.setAfterAvailableBalance(acctInfo.getAvailableBalance());
                    currentMultMchntPreAuthDetailObj.setAfterBalance(acctInfo.getAcctBalance());
                    currentMultMchntPreAuthDetailObj.setAfterFreezeBalance(acctInfo.getFreezeBalance());
                    List<MultiMchntPreAuthDetail> currentMultiMchntPreAuthDetailList = new ArrayList<>();
                    currentMultiMchntPreAuthDetailList.add(currentMultMchntPreAuthDetailObj);
                    virtAcctMultiMchntPreAuthResponse.setMchtPreAuthDetailList(currentMultiMchntPreAuthDetailList);
                    ConvertUtil.convertInput(virtAcctMultiMchntPreAuthResponse);
                }
            } catch (Exception e1) {
                rglog.error(StringUtil.ExceptionToString(e1));
            }
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE,
                        OltpRpcdEnum.BIZ_PROCESS_TIMEOUT.getRespCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC,
                        OltpRpcdEnum.BIZ_PROCESS_TIMEOUT.getRespDesc());
            } catch (Exception e1) {
                rglog.error(StringUtil.ExceptionToString(e));
            }
        }
        return 0;
    }

    @Override
    protected int bizTerminate(String s) {
        return 0;
    }
}
